//@author A0096759E

package logic;
import storage.Storage;
import applogger.AppLogger;


public class CommandDecoder {
	
	
	private static final String STRING_WHITESPACE = " ";
	private static final String STRING_EMPTY = "";
	private static final String ERROR_MSG_INVALID_INPUT = "ERROR! Invalid Input Command. Please Try again!";
	private CommandChecker commandChecker;
	private ScheduleSorter sorter;
	private ScheduleSearcher searcher;
	private ScheduleHelp helper;
	private ScheduleAdder adder;
	private ScheduleDisplay displayer;
	private ScheduleUndoer undoer;
	private ScheduleRedoer redoer;
	private ScheduleMarker marker;
	private ScheduleDeleter deleter;
	private ScheduleModify modifier;

	/**
	 * Constructor for command decoder. Takes in the current LifeShelf storage
	 * @param eventsList
	 */
	public CommandDecoder(Storage eventsList) {
		commandChecker = new CommandChecker();
		helper = new ScheduleHelp();
		adder = new ScheduleAdder(eventsList);
		deleter = new ScheduleDeleter(eventsList);
		undoer = new ScheduleUndoer(eventsList);
		redoer = new ScheduleRedoer(eventsList);
		marker = new ScheduleMarker(eventsList);
		sorter = new ScheduleSorter(eventsList);
		searcher = new ScheduleSearcher(eventsList, sorter);
		modifier = new ScheduleModify(eventsList, adder, undoer);
		displayer = new ScheduleDisplay(eventsList, sorter, searcher);
	}

	/**
	 * Decodes the user input string and calls the respective methods from the differnt logic classes
	 * @param userInputString
	 * @return
	 */
	public String decodeUserInput(String userInputString) {
		String[] userInputs = userInputString.split(STRING_WHITESPACE, 2);
		if (userInputs.length < 1) {
			return ERROR_MSG_INVALID_INPUT;
		}
		
		String userCommand = userInputs[0];
		assert(userCommand != null);
		String userCommandDetails = STRING_EMPTY;
		if (userInputs.length > 1) userCommandDetails = userInputs[1].trim();
		if (commandChecker.checkAdd(userCommand)) {
			AppLogger.log("User is trying to add an event");
			return adder.addEvent(userCommandDetails, null);
		} else if (commandChecker.checkDelete(userCommand)) {
			AppLogger.log("User is trying to delete an event");
			return deleter.deleteEvent(userCommandDetails);
		} else if (commandChecker.checkDisplay(userCommand)) {
			AppLogger.log("User is trying to display events");
			return displayer.displayEvents(userCommandDetails);
		} else if (commandChecker.checkClear(userCommand)) {
			AppLogger.log("User is trying to clear the storage");
			return deleter.clearEvents();
		} else if (commandChecker.checkSearch(userCommand)) {
			AppLogger.log("User is trying to search for events");
			return searcher.searchEvents(userCommandDetails);
		} else if (commandChecker.checkSort(userCommand)) {
			AppLogger.log("User is trying to sort the storage");
			return sorter.sortEvents(userCommandDetails);
		} else if (commandChecker.checkHelp(userCommand)) {
			AppLogger.log("User is trying to view help list");
			return helper.helpList(userCommandDetails);
		} else if (commandChecker.checkUndo(userCommand)) {
			AppLogger.log("User is trying to undo last command");
			return undoer.undoLast();
		} else if (commandChecker.checkRedo(userCommand)) {
			AppLogger.log("User is trying to undo last command");
			return redoer.redoLast();
		} else if (commandChecker.checkMark(userCommand)) {
			AppLogger.log("User is trying to mark an event");
			return marker.markEvent(userCommandDetails);
		} else if (commandChecker.checkModify(userCommand)) {
			AppLogger.log("User is trying to modify an event");
			return modifier.modifyEvents(userCommandDetails);
		}
		return ERROR_MSG_INVALID_INPUT;
	}
}
